﻿using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;

namespace BioCyber_Infection.Class
{
    class Player
    {
        #region Begin of Declaration

        private int playerIndex; // Índex do Player. Seu identificador.
        private float playerSpeed = 5;
        
        Texture2D playerTexture;
        float camada;

        //Animações
        animacao Stop;
        animacao Forward;

        public float rotation;

        Vector2 pivo;
        float rotation_dx, rotation_dy; //Variáveis utilizadas para fazer o player olhar para o mouse
       
        /// <Position, etc>
        /// Variável fundamental, pois é dela que os PacketWriters
        /// e os PacketReaders se baseiam para enviar e receber informações
        /// através da Rede.
        /// </summary>
        public Vector2 position;
        
        /// <Animacao>
        /// Estrutura dos atributos utilizados na animação do Player.
        /// </summary>
        public struct animacao
        {
            public int quadro_X;
            public int quadro_Y;
            public int qtd_quadros;
            public int quadros_seg;
            public int Y;
            public string nome;
        }
        private string gamerID;


        
        #endregion

        #region Constructor
        public Player(int playerIndex, ContentManager content)
        {
            this.playerIndex = playerIndex;
            playerTexture = content.Load<Texture2D>("Player");

            Stop = new animacao();
            Stop.nome = "Parado";
            Stop.qtd_quadros = 1;
            Stop.quadros_seg = 6;
            Stop.Y = 0;
            Stop.quadro_X = 30;
            Stop.quadro_Y = 31;

            Forward = new animacao();
            Forward.nome = "Andando";
            Forward.qtd_quadros = 3;
            Forward.quadros_seg = 6;
            Forward.Y = 0;
            Forward.quadro_X = 30;
            Forward.quadro_Y = 37;

            this.position = new Vector2(100, 50);
            //this.pivo.X = this.playerTexture.Width / 2;
            //this.pivo.Y = this.playerTexture.Height / 2;
            this.pivo.X = 15;
            this.pivo.Y = 15;
            this.camada = 0;
        }
        #endregion

        #region Update
        /// <Update Summary>
        /// Movimentação do player
        /// </summary>
        public void Update(PlayerIndex playerIndex)
        {
            Engine.keyboard = Keyboard.GetState(playerIndex);
            Engine.gamepad = GamePad.GetState(playerIndex);

            if (Engine.isPressed(Keys.D,Buttons.LeftThumbstickRight))
                position.X += playerSpeed;
            else if (Engine.isPressed(Keys.A,Buttons.LeftThumbstickLeft))
                position.X -= playerSpeed;

            if (Engine.isPressed(Keys.W,Buttons.LeftThumbstickUp))
                position.Y -= playerSpeed;
            else if (Engine.isPressed(Keys.S,Buttons.LeftThumbstickDown))
                position.Y += playerSpeed;

            /// <summary>
            /// Rotina que rotaciona o player e o posiciona na direção do mouse
            /// </summary>
            rotation_dx = Engine.mousePos.X - position.X; //Diferença entre a coordenada X do Player e a coordenada X do mouse.
            rotation_dy = (Engine.mousePos.Y - position.Y) * -1; //Diferença entre a coordenada Y do Player e a coordenada Y do mouse.
                                                                 //OBS: Multiplicada por -1 para forçar uma correspondência com o plano cartesiano comum.

            if (rotation_dx >= 0)
            {
                //Simples aplicação do conceito de arcotangente
                //subtraido de PI/2 e multiplicado por -1 para forçar uma correspondência com a geometria cartesiana comum.
                this.rotation = (float) ((Math.Atan(rotation_dy / rotation_dx) - Math.PI / 2) * -1);
            }
            else
            {
                //Simples aplicação do conceito de arcotangente
                //Praticamente igual ao anterior.
                //A diferença é que somamos PI ao valor final para resolver o problema da duplicidade de valores do arcotangente.
                this.rotation = (float)(((Math.Atan(rotation_dy / rotation_dx) - Math.PI / 2) * -1) + Math.PI);
            }
        }
        #endregion

        #region Draw
        /// <Draw Summary>
        /// Este método desenha o player na tela
        /// </summary>
        public void Draw(NetworkGamer gamer,SpriteBatch spriteBatch, ContentManager content, GameTime gameTime)
        {
            int frame = (int)(gameTime.TotalGameTime.TotalSeconds * Forward.quadros_seg) % Forward.qtd_quadros;

            spriteBatch.Draw(
                playerTexture,
                new Rectangle(
                    (int)position.X,
                    (int)position.Y,
                    Forward.quadro_X,
                    Forward.quadro_Y),
                new Rectangle(
                    frame * Forward.quadro_X,
                    Forward.Y,
                    Forward.quadro_X,
                    Forward.quadro_Y),
                Color.White,
                rotation,
                pivo,
                SpriteEffects.None,
                camada);

            spriteBatch.DrawString(content.Load<SpriteFont>("SpriteFont1"), gamer.Gamertag, new Vector2(position.X,position.Y-40), Color.Green);
        }
        #endregion
    }
}
